package name.cyh.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import name.cyh.mapper.InventoryMapper;
import name.cyh.model.po.Inventory;
import name.cyh.model.to.CommitOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 18433
 */
@Service
public class InventoryServiceImpl {
    @Resource
    private InventoryMapper inventoryMapper;

    /**
     * 锁定库存
     * @param commitOrderListList 1 商品ID，2商品数量
     */
    public void inventoryLocking(List<CommitOrder> commitOrderListList) {

        // 查询商品可用库存数量
        /*
            批处理：
            select inventory.product_id,inventory.available_quantity
            from inventory
            where inventory.product_id in (1,2,3)
         */

        List<Inventory> inventories = new ArrayList<>();
        commitOrderListList.forEach(order -> {
            LambdaQueryWrapper<Inventory> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.select(Inventory::getProductId,Inventory::getAvailableQuantity);
            Inventory inventory = inventoryMapper.selectOne(lambdaQuery.eq(
                    Inventory::getProductId,
                    order.getProductId()
            ));
            if (inventory != null) {
                inventories.add(inventory);
            } else {
                throw new RuntimeException("商品无库存");
            }
        });

        Map<Integer, Integer> map = commitOrderListList.stream().collect((Collectors.toMap(CommitOrder::getProductId, CommitOrder::getQuantity)));

        // 锁定商品库存
        for (Inventory inventory : inventories) {
            int lockNu = inventoryMapper.lockInventoryWithOptimisticLock(
                    map.get(inventory.getProductId()),
                    inventory.getProductId(),
                    inventory.getAvailableQuantity()
            );
            if (lockNu == 0) {
                throw new RuntimeException("库存不足");
            }
        }
    }
}
